# HexEdit 代码分析 #

## HexEdit::WndProc() ##

1. 在`FileOpen()`函数中，记录下了文件在内存Mapping中的起始地址`FileBase`。
2. 并通过`HVM_SETITEMCOUNT`消息，把文件的大小通知给结构体变量`HexView`，**显示过程由此触发**。

	注：结构体变量`HexView`最初是在`HexView::HexViewProc()::WM_CREATE`中被创建，并赋了几个基本不会改变的颜色常量值。

## HexView::HexViewProc() ##

1. 在`HVM_SETITEMCOUNT`处理函数中，计算显示相关的参数，保存到结构体变量`HexView`，并触发`WM_PAINT`消息。
2. `HexView_Paint()`-->`HexView_DrawLine()`一行一行的画。
3. 在中会`HexView_DrawLine()`会先画**Address**列，再同时画**DATA / VALUE**列。
4. 例如，画**Address**列时：
	`DispInfo.Item.Mask = HVIF_ADDRESS;`
    `DispInfo.Item.NumberOfItem = NumberOfItem;`
    `HexView_SendNotify(hWnd, HVN_GETDISPINFO, (LPNMHDR)&DispInfo);`
5. 通知消息`HVN_GETDISPINFO`被父窗口`HexEdit`类的处理函数收到，根据`FileBase`读取数据，赋给`DispInfo`
6. 有了`DispInfo`后就可以继续第四步，画出一行了。



## 主要的结构体 ##

	// 这个结构体即可以用于保存一个Address信息，
	// 也可以用于保存一个十六进制字节的信息: "FF "
    typedef struct _HVITEM {
	    UINT Mask; // 值为HVIF_ADDRESS时：为Address; 
				   // 值为HVIF_BYTE时：为一个十六进制字节"FF"
	    UINT State; // HVIS_MODIFIED是否修改为，修改过为红色
	    ULONG64 Address;
	    SIZE_T NumberOfItem; // 这个字节的偏移地址
	    BYTE Value;	// 这个字节的值
    } HVITEM, *PHVITEM;


    typedef struct _NMHVDISPINFO {
	    NMHDR NmHdr;
	    HVITEM Item;
    } NMHVDISPINFO, *PNMHVDISPINFO;


    typedef struct _NMHEXVIEW {
	    NMHDR NmHdr;
	    HVITEM Item;
    } NMHEXVIEW, *PNMHEXVIEW;


## 重要消息 HexView::HexViewProc() ##

### WM_CREATE ###

结构体变量`HexView`最初是在`WM_CREATE`中被创建，并赋了几个基本不会改变的颜色常量值。

### WM_SETFONT ###

在`WM_SETFONT`中计算**字符大小**、**显示区域**，并保存到结构体变量`HexView`中

        hOldFont = SelectObject(hdc, HexView->hFont);
        GetTextMetrics(hdc, &TextMetric);
		…………
        HexView->WidthChar = TextMetric.tmAveCharWidth;
        HexView->HeightChar = TextMetric.tmHeight;

        HexView->VisibleLines = HexView->HeightView / HexView->HeightChar;
        HexView->VisibleChars = HexView->WidthView / HexView->WidthChar;

### WM_LBUTTONDOWN ###


## 重要函数 ##

### HexView_DrawLine() ###

显示一行数据，先画**Address列**、再通过循环16次，一个字符一个字符地同时画出 **DATA列** 和 **VALUE列**，该字符的**选中反蓝**、**修改变红**，也一同画出来。

### HexView_SetPositionOfColumns() ###

计算 **DATA列** 和 **VALUE列** 左侧起始的偏移地址

	HexView->Line1 = XXX;
	HexView->Line2 = XXX;
